package com.cdn.cretry.aspect;

import com.cdn.cretry.anno.CRetry;
import com.cdn.cretry.enums.DelayStrategyType;
import com.cdn.cretry.strategy.DelayStrategy;
import com.cdn.cretry.component.RetryComponent;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;

/**
 * @author 蔡定努
 * 2024/06/01 23:21
 */
@Aspect
@Slf4j
public class CRetryAspect {


    @Around("@annotation(com.cdn.cretry.anno.CRetry)")
    public Object preAuth(ProceedingJoinPoint point) {
        MethodSignature ms = (MethodSignature) point.getSignature();
        Method method = ms.getMethod();
        CRetry cRetry = method.getAnnotation(CRetry.class);

        DelayStrategyType strategy = cRetry.delayStrategy();
        long l = strategy == DelayStrategyType.FIXED ? cRetry.delay() : cRetry.multiplier();
        DelayStrategy delayStrategy = DelayStrategyType.getDelayStrategy(strategy);
            return RetryComponent.retry(() -> {
                try {
                    return point.proceed();
                } catch (Throwable ex) {
                    throw new RuntimeException(ex);
                }
            }, cRetry.maxRetries(), l, delayStrategy);
        }

}
